package prolog.terms
import scala.collection.mutable._
import java.util.ArrayList
import scala.collection.JavaConversions._

class Copier extends SystemObject {
  val dict = new LinkedHashMap[Var, Var]()

  // Needs implementation : by Aly
  def getMyVars(that: Term): Term = {
    that.reaction(this);
    //return toFun(anAnswer,dict.keySet().iterator());
    return Copier.toFun(Copier.anAnswer, dict.keySet.iterator);

  }

  override def action(place: Term): Term = {

    if (place.isInstanceOf[Var]) {
      val vplace = place.asInstanceOf[Var]
      val root = dict.get(vplace);
      root match {
        case None => {
          val res = new Var()
          dict.put(vplace, res)
          return res
        }
        case Some(v) => {
          return v
        }
      }
    } else return place
  }
}

object Copier {
  final val anAnswer: Const = new Const("answer")

  def toFun(c: Const, e: Iterator[Term]): Term = {
    var V: ArrayList[Term] = EnumerationToVector(e)
    var arity: Int = V.size()
    if (arity == 0)
      return c
    var f: Fun = new Fun(c.name, arity)
    // I need the for loop in here
    for (i <- 0 until arity) {
      f.args(i) = V.get(i).asInstanceOf[Term]
    }
    return f
  }

  /**
   * Reifies an Iterator as a ArrayList.
   * ArrayList.iterator() can give back the iterator if needed.
   * @see Copier
   */
  def EnumerationToVector(e: Iterator[Term]): ArrayList[Term] = {
    var V: ArrayList[Term] = new ArrayList()
    while (e.hasNext) {
      V.add(e.next());
    }
    return V;
  }
  
  def VectorToFun(V: ArrayList[Term]): Fun = {
    var f: Const = V.get(0).asInstanceOf[Cons]
    var arity: Int = V.size() - 1
    var T: Fun = new Fun(f.name, arity)
    for (i <- 0 until arity) {
      T.args(i) = V.get(i + 1).asInstanceOf[Term]
    }
    return T


  }


}